/******************************************************************************

	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010.

	This file is part of the Maxsi Library.

	Maxsi Library is free software: you can redistribute it and/or modify it
	under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or (at your
	option) any later version.

	Maxsi Library is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
	License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with Maxsi Library. If not, see <http://www.gnu.org/licenses/>.

	Maxsi Library
	A powerful Cross-Platform C++ General Purpose Library that allows you to
	efficiently create high-performance and reliable applications.

	MaxsiDefines.h
	General defines.

******************************************************************************/

#ifndef MaxsiDefines_H
#define MaxsiDefines_H

//=============================================================================
//	We need this unix header to detect the BSD platform.
//=============================================================================
#define _LARGE_FILE_API
#define _LARGEFILE64_SOURCE
#define __STDC_LIMIT_MACROS // Needed for INTNN_MAX macros in <stdint.h>
#ifdef __unix__
	#include <sys/param.h>
#endif

//=============================================================================
//	Detect whether we are an Maxsi Library implementation or not.
//=============================================================================
#if defined(Maxsi_Library_Library) || defined(Maxsi_Library_Custom_Implementation)
#define Maxsi_Library_Implementation
#endif

//=============================================================================
//	The Maxsi Technology Project defines the following kinds of releases/
//	compile modes for projects that are part of Maxsi Technology.
//
//	Stable - A strict build with all known bugs fixed and all deprecated code
//	         disabled or removed and all temporary "Remove Me" code removed.
//	
//	Release - A build with all serious bugs fixed and all deprecated code
//	          disabled or removed and all temporary "Remove Me" code removed.
//
//	Beta - A build with no debugging purpose but with deprecated code enabled
//	       and with possible known bugs.
//
//	Debug - A debug build with deprecated code enabled and filled with code
//	        section marked Remove Me.
//
//	To compile in any of these modes, please define one of the following
//	mutually exclusive macros.
//
//	- Maxsi_Stable_Build
//	- Maxsi_Release_Build
//	- Maxsi_Beta_Build
//	- Maxsi_Debug_Build
//=============================================================================

//=============================================================================
//	Rules for compiling a stable version of Maxsi Technology.
//=============================================================================
#if defined(Maxsi_Stable_Build)

	#define Maxsi_Disable_Bugs
	#define Maxsi_Disable_Deprecated

	#ifdef Maxsi_Release_Build
	#undef Maxsi_Release_Build
	#endif

	#ifdef Maxsi_Beta_Build
	#undef Maxsi_Beta_Build
	#endif

	#ifdef Maxsi_Debug_Build
	#undef Maxsi_Debug_Build
	#endif

	#ifdef Maxsi_Ignore_Bugs
	#undef Maxsi_Ignore_Bugs
	#endif

#endif

//=============================================================================
//	Rules for compiling a release version of Maxsi Technology.
//=============================================================================
#if defined(Maxsi_Release_Build)

	#define Maxsi_Disable_Deprecated

	#ifdef Maxsi_Stable_Build
	#undef Maxsi_Stable_Build
	#endif

	#ifdef Maxsi_Beta_Build
	#undef Maxsi_Beta_Build
	#endif

	#ifdef Maxsi_Debug_Build
	#undef Maxsi_Debug_Build
	#endif

	#ifdef Maxsi_Ignore_Bugs
	#undef Maxsi_Ignore_Bugs
	#endif

	#ifdef Maxsi_Disable_Bugs
	#undef Maxsi_Disable_Bugs
	#endif

#endif

//=============================================================================
//	Rules for compiling a beta version of Maxsi Technology.
//=============================================================================
#if defined(Maxsi_Beta_Build)

	// Enable functions that aren't ready for Release Builds.
	#define Maxsi_Beta

	#ifdef Maxsi_Stable_Build
	#undef Maxsi_Stable_Build
	#endif

	#ifdef Maxsi_Release_Build
	#undef Maxsi_Release_Build
	#endif

	#ifdef Maxsi_Debug_Build
	#undef Maxsi_Debug_Build
	#endif

	#ifdef Maxsi_Ignore_Bugs
	#undef Maxsi_Ignore_Bugs
	#endif

	#ifdef Maxsi_Disable_Bugs
	#undef Maxsi_Disable_Bugs
	#endif

	#ifdef Maxsi_Disable_Deprecated
	#undef Maxsi_Disable_Deprecated
	#endif

#endif

//=============================================================================
//	Rules for compiling a debug version of Maxsi Technology.
//=============================================================================
#if defined(Maxsi_Debug_Build)

	// Enable functions that aren't ready for Release Builds.
	#define Maxsi_Beta

	#ifdef Maxsi_Stable_Build
	#undef Maxsi_Stable_Build
	#endif

	#ifdef Maxsi_Release_Build
	#undef Maxsi_Release_Build
	#endif

	#ifdef Maxsi_Beta_Build
	#undef Maxsi_Beta_Build
	#endif

	#ifdef Maxsi_Ignore_Bugs
	#undef Maxsi_Ignore_Bugs
	#endif

	#ifdef Maxsi_Disable_Bugs
	#undef Maxsi_Disable_Bugs
	#endif

	#ifdef Maxsi_Disable_Deprecated
	#undef Maxsi_Disable_Deprecated
	#endif

#endif

//=============================================================================
//	Enable special features that aren't ready for release builds.
//=============================================================================
#ifdef Maxsi_Beta

	// The version specifier for Beta and Debug Builds have -BETA appended.
	#define	Maxsi_BuildVersionFull  Maxsi_BuildVersion _MESTR("-BETA")

	// The Maxsi_Beta and Maxsi_Release macros are mutually exclusive.
	#ifdef Maxsi_Release
	#undef Maxsi_Release
	#endif

#else

	#define	Maxsi_BuildVersionFull  Maxsi_BuildVersion

	// We are not a Maxsi_Beta build.
	#define Maxsi_Release

#endif

//=============================================================================
//	Configuration of optional features.
//=============================================================================
#define Maxsi_Debug_RecodeString
#define Maxsi_Enable_Non_Namespaced_Macros
//#define Maxsi_Follow_RFC_2616_Strictly
#define Maxsi_Support_SSE
#define Maxsi_Support_SSE2
#define Maxsi_Using_Unicode_Internally

//=============================================================================
//	If we are not following RFC 2616 (HTTP/1.1) strictly, then we can enable
//	the Entity-Length header that allows us to specify the length of the
//	entity being transferred, even if we are transferring in chunked mode.
//	This is entirely non-standard code that was accidentally written due to
//	a misunderstanding of the official RFC, but which proved sort of useful.
//	Please note that RFC 2616 sec 7.1 allows us to use extension-headers for
//	the entity-headers, which makes this perfectly legal.
//=============================================================================
#ifndef Maxsi_Follow_RFC_2616_Strictly
#define Maxsi_HTTP_Enable_Entity_Length
#endif

//=============================================================================
//	Configuration of Compiler dependent features.
//=============================================================================

#if defined(__MINGW_H) || defined(__MINGW32__) || defined(__MINGW64__) // Detect if we are using MinGW

	#define Maxsi_Support_MinGW

	#define Maxsi_Support_Buggy_vswprintf

#endif

#if defined(__GNUC__) // Detect if we are using the GNU Compiler Collection

	#define Maxsi_Support_GCC

	#define Maxsi_Support_C_Runtime_Extensions

	#ifdef Maxsi_Support_MinGW

		#define Maxsi_Compiler_String "MinGW"

	#else
		
		#define Maxsi_Compiler_String "GCC"

	#endif

#endif

#ifdef _MSC_VER // Detect the damn Microsoft Compiler

	#define Maxsi_Support_VS_Version _MSC_VER

	// Detect what version of Visual Studio we are using.
	#if ( _MSC_VER => 1600 && _MSC_VER < 1700 )
	
		#define Maxsi_Compiler_String "Visual-Studio-2010"
		#define Maxsi_Support_VS 2010
		#define Maxsi_Support_VS2010
	
	#elif ( _MSC_VER => 1500 )
	
		#define Maxsi_Compiler_String "Visual-Studio-2008"	
		#define Maxsi_Support_VS 2008	
		#define Maxsi_Support_VS2008
	
	#elif ( _MSC_VER => 1400 )
	
		#define Maxsi_Compiler_String "Visual-Studio-2005"	
		#define Maxsi_Support_VS 2005	
		#define Maxsi_Support_VS2005
	
	#elif( _MSC_VER => 1310 )
	
		#define Maxsi_Compiler_String "Visual-Studio-2003"	
		#define Maxsi_Support_VS 2003	
		#define Maxsi_Support_VS2003
	
	#elif( _MSC_VER => 1300 )
	
		#define Maxsi_Compiler_String "Visual-Studio-2002"
		#define Maxsi_Support_VS 2002
		#define Maxsi_Support_VS2002

	#define 

		#warning "Which version of Visual Studio are you using? Please edit MaxsiDefines.h"

		#define Maxsi_Compiler_String "Visual-Studio-Unknown"	
		#define Maxsi_Support_VS 9999	
		#define Maxsi_Support_VSUNKNOWN

	#endif

	// Microsoft Visual Studio doesn't support the useful and lovely stdint.h header!
	#define Maxsi_Using_MSC_StdInt

#endif

#ifdef _MSC_VER_REGULAR // Detect the regular Microsoft Compiler

	#define Maxsi_Support_Regular_Visual_Studio

#endif

#ifndef Maxsi_Compiler_String
	
	#define Maxsi_Compiler_String "Unknown-Compiler"

#endif

//=============================================================================
//	Configuration of Operating System dependent features.
//=============================================================================

#if defined(WIN32) // Detect Windows 32-bit or 64-bit
	
	// We are using the Windows platform.
	#define Maxsi_Support_W32

	#define Maxsi_OS_String "Windows"

#endif

#if defined(WIN64) // Detect Windows 64-bit

	// We are even using the Windows 64-bit platform. (WIN32 is always defined, even if WIN64 is too).
	#define Maxsi_Support_W64

#endif

#if defined(__unix__) // Detect a UNIX-like system.

	// This system is UNIX-like.
	#define Maxsi_Support_UNIX

#endif

#if defined(BSD) // Detect a BSD system

	#define Maxsi_Support_BSD	

	#define Maxsi_OS_String "BSD"

	// The BSD platform is POSIX compliant.
	#define Maxsi_Support_POSIX
	
	// We can use the SO_NOSIGPIPE socket option
	#define Maxsi_Support_NoSigPipe

#endif

#if defined(linux) // Detect the Linux Kernel

	// We are using the Linux platform.
	#define Maxsi_Support_Linux

	// The Linux Kernel implements the Epoll interface for async IO
	#define Maxsi_Support_Epoll

#endif

#if defined(Maxsi_Support_GCC) && defined(Maxsi_Support_Linux) // Detect the GNU/Linux Platform

	// We are using GNU
	#define Maxsi_Support_GNU

	// We are using GNU/Linux
	#define Maxsi_Support_GNU_LINUX

	// The GNU/Linux platform is POSIX compliant.
	#define Maxsi_Support_POSIX

	#define Maxsi_OS_String "GNU/Linux"

#endif

#if defined(Maxsi_Support_POSIX)

	// We support the GTK+ Window System on the POSIX platform.
	#define Maxsi_Support_GTK

	// If POSIX is supported then the Pthreads multi-threading library is too.
	#define Maxsi_Support_Pthreads

	// The iconv text-encoding conversion functions are part of POSIX:2001.
	#define Maxsi_Using_libiconv

	// We have successfully implemented stack allocation here.
	#define Maxsi_Stack_Alloc_Supported

	#define Maxsi_Support_Buggy_vswprintf

	// We are using xz-utils (liblzma) for compression.
	#define Maxsi_Support_liblzma

	// We are using GnuTLS for TLS connections.
	#define Maxsi_Support_GNUTLS

#endif

//=============================================================================
//	Generate a User-Agent string for this build.
//=============================================================================
#ifndef Maxsi_User_Agent_String
#define Maxsi_User_Agent_String "MaxsiLibrary/" Maxsi_Build_Name "-" Maxsi_Build_Version_String " (" Maxsi_Compiler_String  "; " Maxsi_OS_String ")"
#endif

//=============================================================================
//	Macros to control whether we are using namespaces or not.
//=============================================================================
#define BeginMaxsiNamespace namespace Maxsi {
#define EndMaxsiNamespace }
#define UsingMaxsiNamespace using namespace Maxsi;

#define BeginMaxsiUINamespace namespace MaxsiUI {
#define EndMaxsiUINamespace }
#define UsingMaxsiUINamespace using namespace MaxsiUI;

//=============================================================================
//	Declaration of the common namespaces, if we use them.
//=============================================================================
BeginMaxsiNamespace
EndMaxsiNamespace

//=============================================================================
//	Define a global version identification string.
//=============================================================================
#define MaxsiLibrary_VersionInfo _MESTR("Application/x-MaxsiLIbrary/") _MESTR(Maxsi_BuildName) _MESTR("/") _MESTR(Maxsi_BuildVersion) _MESTR("/") _MESTR(__DATE__)

#endif

